
struct years <: AbstractGranularUnit end
struct quarters <: AbstractGranularUnit end
struct months <: AbstractGranularUnit end
struct days <: AbstractGranularUnit end
struct hours <: AbstractGranularUnit end
struct quarterhours <: AbstractGranularUnit end
struct minutes <: AbstractGranularUnit end
struct seconds <: AbstractGranularUnit end
struct milliseconds <: AbstractGranularUnit end
struct microseconds <: AbstractGranularUnit end
struct nanoseconds <: AbstractGranularUnit end

for (T,U) in ((:Years, :years), (:Quarters, :quarters), (:Months, :months), (:Days, :days), (:Hours, :hours),
            (:QuarterHours, :quarterhours), (:Minutes, :minutes), (:Seconds, :seconds),
            (:Milliseconds, :milliseconds), (:Microseconds, :microseconds), (:Nanoseconds, :nanoseconds))
    @eval Base.:(*)(x::I, u::Type{$U}) where I<:Union{Int64, Int32, Int16, Int8} = $T(Int64(x))
    @eval Base.:(*)(u::Type{$U}, x::I) where I<:Union{Int64, Int32, Int16, Int8} = $T(Int64(x))
end

nanoseconds(x::T) where T<:SimpleClock = value(x)
microseconds(x::T) where T<:SimpleClock = fld(value(x), NANOSECONDS_PER_MICROSECOND)
milliseconds(x::T) where T<:SimpleClock = fld(value(x), NANOSECONDS_PER_MILLISECOND)
seconds(x::T) where T<:SimpleClock = fld(value(x), NANOSECONDS_PER_SECOND)
minutes(x::T) where T<:SimpleClock = fld(value(x), NANOSECONDS_PER_MINUTE)
hours(x::T) where T<:SimpleClock = fld(value(x), NANOSECONDS_PER_HOUR)
days(x::T) where T<:SimpleClock = fld(value(x), NANOSECONDS_PER_DAY)
weeks(x::T) where T<:SimpleClock = fld(value(x), NANOSECONDS_PER_WEEK)

Nanoseconds(x::T) where T<:SimpleClock = Nanoseconds(nanoseconds(x))
Microseconds(x::T) where T<:SimpleClock = Microseconds(microseconds(x))
Milliseconds(x::T) where T<:SimpleClock = Milliseconds(milliseconds(x))
Seconds(x::T) where T<:SimpleClock = Seconds(seconds(x))
Minutes(x::T) where T<:SimpleClock = Minutes(minutes(x))
Hours(x::T) where T<:SimpleClock = Hours(hours(x))
Days(x::T) where T<:SimpleClock = Days(days(x))
Weeks(x::T) where T<:SimpleClock = Weeks(weeks(x))


struct yr <: AbstractGranularUnit end
struct qy <: AbstractGranularUnit end
struct mo <: AbstractGranularUnit end
struct dy <: AbstractGranularUnit end
struct hr <: AbstractGranularUnit end
struct qh <: AbstractGranularUnit end
struct mi <: AbstractGranularUnit end
struct sc <: AbstractGranularUnit end
struct ms <: AbstractGranularUnit end
struct μs <: AbstractGranularUnit end
struct us <: AbstractGranularUnit end
struct ns <: AbstractGranularUnit end

for (T,U) in ((:Years, :yr), (:Quarters, :qy), (:Months, :mo), (:Days, :dy), (:Hours, :hr),
            (:QuarterHour, :qh), (:Minutes, :mi), (:Seconds, :sc),
            (:Milliseconds, :ms), (:Microseconds, :us), (:Microseconds, :μs), (:Nanoseconds, :ns))
    @eval Base.:(*)(x::I, u::Type{$U}) where I<:Union{Int64, Int32, Int16, Int8} = $T(Int64(x))
    @eval Base.:(*)(u::Type{$U}, x::I) where I<:Union{Int64, Int32, Int16, Int8} = $T(Int64(x))
end
